package crivia.ecp.carry.html;

import java.util.HashMap;
import java.util.Map;

import crivia.ecp.carry.html.DO;
import crivia.ecp.common.ECR;
import crivia.ecp.exception.WrongDocumentObject;
/**
 * Document Object.<br/>
 * Abstract.
 * See X Implement.
 */
public abstract class DO {
	
	public final static String ExceptionString_CellsOver = "Cells Over.";
	public final static WrongDocumentObject Exception_CellsOver(String s){
		return new WrongDocumentObject(ExceptionString_CellsOver
			+ "\n" + s);
	}
	
	protected abstract String name();
	
	protected abstract String innerHTML();
	
	private boolean show = true;
	public boolean isShow() {
		return show;
	}
	public DO setShow(boolean show) {
		this.show = show;
		return this;
	}
	
	private String cssClass;
	public String getCssClass() {
		return cssClass;
	}
	public DO setCssClass(String cssClass) {
		this.cssClass = cssClass;
		return this;
	}

	private Map<String,String> attrs = new HashMap<String, String>();
	public Map<String, String> getAttrs() {
		return attrs;
	}
	public DO setAttrs(Map<String, String> attrs) {
		this.attrs = attrs;
		return this;
	}
	public String getAttr(String key){
		return attrs.get(key);
	}
	public DO addAttr(String key, String value) {
		attrs.put(key, value);
		return this;
	}
	public DO addAttr(String key, int value) {
		attrs.put(key, value + "");
		return this;
	}

	private Map<String,String> styleMap = new HashMap<String, String>();
	public Map<String, String> getStyleMap() {
		return styleMap;
	}
	public DO setStyleMap(Map<String, String> styleMap) {
		this.styleMap = styleMap;
		return this;
	}
	public String getStyle(String key) {
		return styleMap.get(key);
	}
	public DO addStyle(String key, String value) {
		styleMap.put(key, value);
		return this;
	}
	
	@Override
	public String toString() {
		String name = name();
		if (null == name){
			throw new WrongDocumentObject("Document Object Name Is Null.");
		}
		if (! attrs.containsKey("class") && ECR.hasCondition(cssClass)){
			addAttr("class", cssClass);
		}
		if (! attrs.containsKey("style") && styleMap.size() > 0){
			StringBuilder tStr = new StringBuilder();
			for (String styleName : styleMap.keySet()){
				String v = styleMap.get(styleName);
				if (! ECR.hasCondition(v)){
					continue;
				}
				tStr.append(styleName).append(" : ").append(v).append(";");
			}
			addAttr("style", tStr.toString());
		}
		StringBuilder tStr = new StringBuilder("<").append(name);
		for (String attrName : attrs.keySet()){
			String v = attrs.get(attrName);
			if (! ECR.hasCondition(v)){
				continue;
			}
			tStr.append(" ")
			.append(attrName).append("=").append(attr(v));
		}
		
		String innerHTML = innerHTML();
		if (innerHTML == null){
			tStr.append("/>");
		} else {
			tStr.append(">")
			.append(innerHTML)
			.append("</").append(name).append(">");
		}
		
		return isShow() ? tStr.toString() : "";
	}
	
	public static String attr(String s){
		return "\"" + ECR.ns(s) + "\"";
	}

}
